home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmbase-grok-1.2 / prefwin.c < prev    next >
C/C++ Source or Header  |  1995-06-25  |  15KB  |  452 lines

  1. /*
  2.  * Create and destroy the preferences popup, and read and write the
  3.  * preferences file. The printing configuration is also stored in the
  4.  * pref structure, but the user interface for it is in printwin.c.
  5.  *
  6.  *    read_preferences()
  7.  *    write_preferences()
  8.  *    destroy_preference_popup()
  9.  *    create_preference_popup()
  10.  */
  11.  
  12. #include "config.h"
  13. #include <stdlib.h>
  14. #include <X11/Xos.h>
  15. #include <Xm/Xm.h>
  16. #include <Xm/DialogS.h>
  17. #include <Xm/Form.h>
  18. #include <Xm/LabelP.h>
  19. #include <Xm/LabelG.h>
  20. #include <Xm/PushBP.h>
  21. #include <Xm/PushBG.h>
  22. #include <Xm/Text.h>
  23. #include <Xm/ToggleB.h>
  24. #include <Xm/Separator.h>
  25. #include <Xm/Protocols.h>
  26. #include "grok.h"
  27. #include "form.h"
  28. #include "proto.h"
  29.  
  30. static void done_callback (Widget, int, XmToggleButtonCallbackStruct *);
  31. static void spool_callback(Widget, int, XmToggleButtonCallbackStruct *);
  32.  
  33. extern Display    *display;    /* everybody uses the same server */
  34. extern Pixel    color[NCOLS];    /* colors: COL_* */
  35. extern int    errno;
  36. extern Widget    toplevel;    /* top-level shell for error popup */
  37. struct pref    pref;        /* global preferences */
  38.  
  39. static BOOL    have_shell;    /* message popup exists if TRUE */
  40. static Widget    shell;        /* popup menu shell */
  41. static Widget    w_spoola;    /* ascii spool text */
  42. static Widget    w_spoolp;    /* ascii spool text */
  43. static Widget    w_lines;    /* summary lines text */
  44. static Widget    w_scale;    /* card scale text */
  45. static BOOL    modified;    /* preferences have changed */
  46.  
  47.  
  48. /*
  49.  * destroy a popup. Remove it from the screen, and destroy its widgets.
  50.  * It's too much trouble to keep them for next time.
  51.  */
  52.  
  53. void destroy_preference_popup(void)
  54. {
  55.     if (have_shell) {
  56.         int    i;
  57.         double    d;
  58.         char    *p;
  59.  
  60.         p = read_text_button(w_spoola, 0);
  61.         if (*p && strcmp(p, pref.pspooler_a)) {
  62.             free(pref.pspooler_a);
  63.             pref.pspooler_a = mystrdup(p);
  64.             modified = TRUE;
  65.         }
  66.         p = read_text_button(w_spoolp, 0);
  67.         if (*p && strcmp(p, pref.pspooler_p)) {
  68.             free(pref.pspooler_a);
  69.             pref.pspooler_p = mystrdup(p);
  70.             modified = TRUE;
  71.         }
  72.         p = read_text_button(w_lines,  0);
  73.         if ((i = atoi(p)) > 0 && i < 80) {
  74.             pref.sumlines = i;
  75.             modified = TRUE;
  76.         }
  77.         p = read_text_button(w_scale,  0);
  78.         if ((d = atof(p)) > 0.1 && d < 10.0) {
  79.             pref.scale = d;
  80.             modified = TRUE;
  81.         }
  82.         XtPopdown(shell);
  83.         XtDestroyWidget(shell);
  84.         have_shell = FALSE;
  85.         if (modified)
  86.             write_preferences();
  87.         modified = FALSE;
  88.     }
  89. }
  90.  
  91.  
  92. /*
  93.  * create a preference popup as a separate application shell. The popup is
  94.  * initialized with data from pref.
  95.  */
  96.  
  97. static struct flag { BOOL *value; char *text; } flags[] = {
  98.     { &pref.ampm,        "12 hour mode (am/pm)"            },
  99.     { &pref.mmddyy,        "Month/day/year mode"            },
  100.     { &pref.query2search,    "Show query search expressions"        },
  101.     { &pref.letters,    "Enable search by initial letter"    },
  102.     { &pref.allwords,    "Letter search checks all words"    },
  103.     { &pref.incremental,    "Incremental searches and queries"    },
  104.     { &pref.uniquedb,    "Don't show duplicate databases"    },
  105.     { 0,            0                    }
  106. };
  107.  
  108. static void flag_callback(Widget, struct flag*, XmToggleButtonCallbackStruct*);
  109.  
  110. void create_preference_popup(void)
  111. {
  112.     Widget            form, w, sep;
  113.     Arg            args[20];
  114.     int            n;
  115.     Atom            closewindow;
  116.     struct flag        *flag;
  117.  
  118.     destroy_preference_popup();
  119.  
  120.     n = 0;
  121.     XtSetArg(args[n], XmNdeleteResponse,    XmDO_NOTHING);        n++;
  122.     XtSetArg(args[n], XmNiconic,        False);            n++;
  123.     shell = XtAppCreateShell("Grok Preferences", "Grok",
  124.             applicationShellWidgetClass, display, args, n);
  125.     set_icon(shell, 1);
  126.     form = XtCreateManagedWidget("prefform", xmFormWidgetClass,
  127.             shell, NULL, 0);
  128.     XtAddCallback(form, XmNhelpCallback,
  129.             (XtCallbackProc)help_callback, (XtPointer)"pref");
  130.  
  131.                             /*-- flags --*/
  132.     for (w=0, flag=flags; flag->value; flag++) {
  133.        n = 0;
  134.        XtSetArg(args[n], XmNtopAttachment,    w ? XmATTACH_WIDGET
  135.                           : XmATTACH_FORM);    n++;
  136.        XtSetArg(args[n], XmNtopWidget,    w);            n++;
  137.        XtSetArg(args[n], XmNtopOffset,    8);            n++;
  138.        XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  139.        XtSetArg(args[n], XmNleftOffset,    16);            n++;
  140.        XtSetArg(args[n], XmNselectColor,    color[COL_TOGGLE]);    n++;
  141.        XtSetArg(args[n], XmNset,        *flag->value);        n++;
  142.        XtSetArg(args[n], XmNhighlightThickness,0);            n++;
  143.        w = XtCreateManagedWidget(flag->text,
  144.             xmToggleButtonWidgetClass, form, args, n);
  145.        XtAddCallback(w, XmNvalueChangedCallback,
  146.             (XtCallbackProc)flag_callback, (XtPointer)flag);
  147.        XtAddCallback(w, XmNhelpCallback,
  148.               (XtCallbackProc)help_callback, (XtPointer)"pref");
  149.     }
  150.  
  151.                             /*-- print spooler --*/
  152.     n = 0;
  153.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  154.     XtSetArg(args[n], XmNtopWidget,        w);            n++;
  155.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  156.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  157.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  158.     sep = XtCreateManagedWidget("ps1",
  159.                 xmSeparatorWidgetClass, form, args, n);
  160.  
  161.     n = 0;
  162.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  163.     XtSetArg(args[n], XmNtopWidget,        sep);            n++;
  164.     XtSetArg(args[n], XmNtopOffset,        12);            n++;
  165.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  166.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  167.     w = XtCreateManagedWidget("PostScript print spooler:",
  168.                 xmLabelWidgetClass, form, args, n);
  169.  
  170.     n = 0;
  171.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  172.     XtSetArg(args[n], XmNtopWidget,        sep);            n++;
  173.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  174.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_WIDGET);    n++;
  175.     XtSetArg(args[n], XmNleftWidget,    w);            n++;
  176.     XtSetArg(args[n], XmNleftOffset,    8);            n++;
  177.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  178.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  179.     XtSetArg(args[n], XmNwidth,        200);            n++;
  180.     XtSetArg(args[n], XmNbackground,    color[COL_TEXTBACK]);    n++;
  181.     w_spoolp = XtCreateManagedWidget("spoolp",
  182.                 xmTextWidgetClass, form, args, n);
  183.     XtAddCallback(w_spoolp, XmNactivateCallback,
  184.                 (XtCallbackProc)spool_callback, NULL);
  185.  
  186.     n = 0;
  187.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  188.     XtSetArg(args[n], XmNtopWidget,        w_spoolp);        n++;
  189.     XtSetArg(args[n], XmNtopOffset,        12);            n++;
  190.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  191.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  192.     w = XtCreateManagedWidget("ASCII print spooler:",
  193.                 xmLabelWidgetClass, form, args, n);
  194.  
  195.     n = 0;
  196.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  197.     XtSetArg(args[n], XmNtopWidget,        w_spoolp);        n++;
  198.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  199.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET);    n++;
  200.     XtSetArg(args[n], XmNleftWidget,    w_spoolp);        n++;
  201.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  202.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  203.     XtSetArg(args[n], XmNwidth,        200);            n++;
  204.     XtSetArg(args[n], XmNbackground,    color[COL_TEXTBACK]);    n++;
  205.     w_spoola = XtCreateManagedWidget("spoola",
  206.                 xmTextWidgetClass, form, args, n);
  207.     XtAddCallback(w_spoola, XmNactivateCallback,
  208.                 (XtCallbackProc)spool_callback, NULL);
  209.  
  210.                             /*-- nlines, scale --*/
  211.     n = 0;
  212.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  213.     XtSetArg(args[n], XmNtopWidget,        w_spoola);        n++;
  214.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  215.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  216.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  217.     sep = XtCreateManagedWidget("ps2",
  218.                 xmSeparatorWidgetClass, form, args, n);
  219.  
  220.     n = 0;
  221.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  222.     XtSetArg(args[n], XmNtopWidget,        sep);            n++;
  223.     XtSetArg(args[n], XmNtopOffset,        12);            n++;
  224.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  225.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  226.     w = XtCreateManagedWidget("Summary lines:",
  227.                 xmLabelWidgetClass, form, args, n);
  228.  
  229.     n = 0;
  230.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  231.     XtSetArg(args[n], XmNtopWidget,        sep);            n++;
  232.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  233.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET);    n++;
  234.     XtSetArg(args[n], XmNleftWidget,    w_spoolp);        n++;
  235.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  236.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  237.     XtSetArg(args[n], XmNwidth,        200);            n++;
  238.     XtSetArg(args[n], XmNbackground,    color[COL_TEXTBACK]);    n++;
  239.     w_lines = XtCreateManagedWidget("lines",
  240.                 xmTextWidgetClass, form, args, n);
  241.  
  242.     n = 0;
  243.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  244.     XtSetArg(args[n], XmNtopWidget,        w_lines);        n++;
  245.     XtSetArg(args[n], XmNtopOffset,        12);            n++;
  246.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  247.     XtSetArg(args[n], XmNleftOffset,    16);            n++;
  248.     w = XtCreateManagedWidget("Card scaling factor:",
  249.                 xmLabelWidgetClass, form, args, n);
  250.  
  251.     n = 0;
  252.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  253.     XtSetArg(args[n], XmNtopWidget,        w_lines);        n++;
  254.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  255.     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET);    n++;
  256.     XtSetArg(args[n], XmNleftWidget,    w_spoolp);        n++;
  257.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  258.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  259.     XtSetArg(args[n], XmNwidth,        200);            n++;
  260.     XtSetArg(args[n], XmNbackground,    color[COL_TEXTBACK]);    n++;
  261.     w_scale = XtCreateManagedWidget("scale",
  262.                 xmTextWidgetClass, form, args, n);
  263.  
  264.                             /*-- buttons --*/
  265.     n = 0;
  266.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  267.     XtSetArg(args[n], XmNtopWidget,        w_scale);        n++;
  268.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  269.     XtSetArg(args[n], XmNleftAttachment,    XmATTACH_FORM);        n++;
  270.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  271.     sep = XtCreateManagedWidget("ps2",
  272.                 xmSeparatorWidgetClass, form, args, n);
  273.  
  274.     n = 0;
  275.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  276.     XtSetArg(args[n], XmNtopWidget,        sep);            n++;
  277.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  278.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  279.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  280.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);        n++;
  281.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  282.     XtSetArg(args[n], XmNwidth,        80);            n++;
  283.     w = XtCreateManagedWidget("Done",
  284.                 xmPushButtonWidgetClass, form, args, n);
  285.     XtAddCallback(w, XmNactivateCallback,
  286.             (XtCallbackProc)done_callback, (XtPointer)0);
  287.     XtAddCallback(w, XmNhelpCallback,
  288.             (XtCallbackProc)help_callback, (XtPointer)"pref_done");
  289.  
  290.     n = 0;
  291.     XtSetArg(args[n], XmNtopAttachment,    XmATTACH_WIDGET);    n++;
  292.     XtSetArg(args[n], XmNtopWidget,        sep);            n++;
  293.     XtSetArg(args[n], XmNtopOffset,        8);            n++;
  294.     XtSetArg(args[n], XmNbottomAttachment,    XmATTACH_FORM);        n++;
  295.     XtSetArg(args[n], XmNbottomOffset,    8);            n++;
  296.     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_WIDGET);    n++;
  297.     XtSetArg(args[n], XmNrightWidget,    w);            n++;
  298.     XtSetArg(args[n], XmNrightOffset,    8);            n++;
  299.     XtSetArg(args[n], XmNwidth,        80);            n++;
  300.     w = XtCreateManagedWidget("Help",
  301.                 xmPushButtonWidgetClass, form, args, n);
  302.     XtAddCallback(w, XmNactivateCallback,
  303.             (XtCallbackProc)help_callback, (XtPointer)"pref");
  304.     XtAddCallback(w, XmNhelpCallback,
  305.             (XtCallbackProc)help_callback, (XtPointer)"pref");
  306.  
  307.     XtPopup(shell, XtGrabNone);
  308.     closewindow = XmInternAtom(display, "WM_DELETE_WINDOW", False);
  309.     XmAddWMProtocolCallback(shell, closewindow,
  310.             (XtCallbackProc)done_callback, (XtPointer)0);
  311.     print_text_button_s(w_spoola, pref.pspooler_a);
  312.     print_text_button_s(w_spoolp, pref.pspooler_p);
  313.     print_text_button(w_lines, "%d", pref.sumlines);
  314.     print_text_button(w_scale, "%g", pref.scale);
  315.     have_shell = TRUE;
  316. }
  317.  
  318.  
  319. /*-------------------------------------------------- callbacks --------------*/
  320. /*
  321.  * All of these routines are direct X callbacks.
  322.  */
  323.  
  324. /*ARGSUSED*/
  325. static void done_callback(
  326.     Widget                widget,
  327.     int                item,
  328.     XmToggleButtonCallbackStruct    *data)
  329. {
  330.     destroy_preference_popup();
  331. }
  332.  
  333.  
  334. /*ARGSUSED*/
  335. static void flag_callback(
  336.     Widget                widget,
  337.     struct flag            *flag,
  338.     XmToggleButtonCallbackStruct    *data)
  339. {
  340.     *flag->value = data->set;
  341.     if (flag->value == &pref.uniquedb)
  342.         remake_dbase_pulldown();
  343.     modified = TRUE;
  344. }
  345.  
  346.  
  347. /*ARGSUSED*/
  348. static void spool_callback(
  349.     Widget                widget,
  350.     int                item,
  351.     XmToggleButtonCallbackStruct    *data)
  352. {
  353.     (void)read_text_button(w_spoola, &pref.pspooler_a);
  354.     (void)read_text_button(w_spoolp, &pref.pspooler_p);
  355.     modified = TRUE;
  356. }
  357.  
  358.  
  359. /*-------------------------------------------------- file i/o ---------------*/
  360. /*
  361.  * write pref struct to preferences file, used whenever popup is destroyed
  362.  * if some button in it had been pressed
  363.  */
  364.  
  365. void write_preferences(void)
  366. {
  367.     char        *path;        /* path of preferences file */
  368.     FILE        *fp;        /* preferences file */
  369.  
  370.     path = resolve_tilde(PREFFILE, 0);
  371.     if (!(fp = fopen(path, "w"))) {
  372.         create_error_popup(toplevel, errno,
  373.             "Failed to write to preferences file\n%s", path);
  374.         return;
  375.     }
  376.     fprintf(fp, "ampm    %s\n",    pref.ampm      ? "yes" : "no");
  377.     fprintf(fp, "mmddyy    %s\n",    pref.mmddyy      ? "yes" : "no");
  378.     fprintf(fp, "q2s    %s\n",    pref.query2search ? "yes" : "no");
  379.     fprintf(fp, "letter    %s\n",    pref.letters      ? "yes" : "no");
  380.     fprintf(fp, "allword    %s\n",    pref.allwords      ? "yes" : "no");
  381.     fprintf(fp, "incr    %s\n",    pref.incremental  ? "yes" : "no");
  382.     fprintf(fp, "unique    %s\n",    pref.uniquedb     ? "yes" : "no");
  383.     fprintf(fp, "scale    %g\n",    pref.scale);
  384.     fprintf(fp, "lines    %d\n",    pref.sumlines);
  385.     fprintf(fp, "pselect    %c\n",    pref.pselect);
  386.     fprintf(fp, "pformat    %c\n",    pref.pformat);
  387.     fprintf(fp, "pqual    %c\n",    pref.pquality);
  388.     fprintf(fp, "pdevice    %c\n",    pref.pdevice);
  389.     fprintf(fp, "pspoola    %s\n",    pref.pspooler_a);
  390.     fprintf(fp, "pspoolp    %s\n",    pref.pspooler_p);
  391.     fprintf(fp, "pfile    %s\n",    pref.pfile ? pref.pfile : "");
  392.     fclose(fp);
  393. }
  394.  
  395.  
  396. /*
  397.  * read preferences file into pref struct, done by main() when starting up
  398.  */
  399.  
  400. void read_preferences(void)
  401. {
  402.     char        *path;        /* path of preferences file */
  403.     FILE        *fp;        /* preferences file */
  404.     char        line[1024];    /* line from file */
  405.     char        *p;        /* for scanning line */
  406.     char        *key;        /* first char of first word in line */
  407.     int        value;        /* value of second word in line */
  408.  
  409.     pref.letters    = TRUE;
  410.     pref.scale    = 1.0;
  411.     pref.sumlines    = 8;
  412.     pref.pselect    = 'S';
  413.     pref.pformat    = 'S';
  414.     pref.pquality    = 'A';
  415.     pref.pdevice    = 'P';
  416.     pref.pspooler_a    = mystrdup(PSPOOL_A);
  417.     pref.pspooler_p    = mystrdup(PSPOOL_P);
  418.  
  419.     path = resolve_tilde(PREFFILE, 0);
  420.     if (!(fp = fopen(path, "r")))
  421.         return;
  422.     for (;;) {
  423.         if (!fgets(line, 1023, fp))
  424.             break;
  425.         for (p=line; *p == ' ' || *p == '\t'; p++);
  426.         if (*p == '#' || !*p)
  427.             continue;
  428.         for (key=p; *p && *p != ' ' && *p != '\t'; p++);
  429.         if (*p) *p++ = 0;
  430.         for (; *p == ' ' || *p == '\t'; p++);
  431.         value = (*p&~32) == 'T' || (*p&~32) == 'Y' ? 1 : atoi(p);
  432.  
  433.         if (!strcmp(key, "ampm"))    pref.ampm     = value;
  434.         if (!strcmp(key, "mmddyy"))    pref.mmddyy     = value;
  435.         if (!strcmp(key, "q2s"))    pref.query2search= value;
  436.         if (!strcmp(key, "letter"))    pref.letters     = value;
  437.         if (!strcmp(key, "allword"))    pref.allwords     = value;
  438.         if (!strcmp(key, "incr"))    pref.incremental = value;
  439.         if (!strcmp(key, "unique"))    pref.uniquedb     = value;
  440.         if (!strcmp(key, "scale"))    pref.scale     = atof(p);
  441.         if (!strcmp(key, "lines"))    pref.sumlines     = value;
  442.         if (!strcmp(key, "pselect"))    pref.pselect     = *p;
  443.         if (!strcmp(key, "pformat"))    pref.pformat     = *p;
  444.         if (!strcmp(key, "pqual"))    pref.pquality     = *p;
  445.         if (!strcmp(key, "pdevice"))    pref.pdevice     = *p;
  446.         if (!strcmp(key, "pspoola"))    pref.pspooler_a     = mystrdup(p);
  447.         if (!strcmp(key, "pspoolp"))    pref.pspooler_p     = mystrdup(p);
  448.         if (!strcmp(key, "pfile"))    pref.pfile     = mystrdup(p);
  449.     }
  450.     fclose(fp);
  451. }
  452.